﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace QFrameworkOne.Module {
    /// <summary>
    /// 计算字符串的哈希值（MD5、SHA）
    /// </summary>
    public class HashHelper : QModuleBase, IQMoudule {
        string IQMoudule.Module_Name => "HashHelper";

        string IQMoudule.Module_Author => "（原作者：北风其凉）DealiAxy修改为QModule";

        string IQMoudule.Module_Mail => "admin@deali.cn";

        string IQMoudule.Module_Website => "https://my.oschina.net/Tsybius2014/blog/294249";

        string IQMoudule.Module_Description => "C# 计算字符串的哈希值（MD5、SHA）";

        QComponentVersion IQMoudule.Module_Version => new QComponentVersion()
            {Major = 1, Minor = 0, Update = 6, Label = QComponentVersionLabel.Beta};

        /// <summary>
        /// 计算32位MD5码
        /// </summary>
        /// <param name="word">字符串</param>
        /// <param name="toUpper">返回哈希值格式 true：英文大写，false：英文小写</param>
        /// <returns></returns>
        public static string Hash_MD5_32(string word, bool toUpper = true) {
            try {
                System.Security.Cryptography.MD5CryptoServiceProvider MD5CSP
                    = new System.Security.Cryptography.MD5CryptoServiceProvider();

                byte[] bytValue = System.Text.Encoding.UTF8.GetBytes(word);
                byte[] bytHash = MD5CSP.ComputeHash(bytValue);
                MD5CSP.Clear();

                //根据计算得到的Hash码翻译为MD5码
                string sHash = "", sTemp = "";
                for (int counter = 0; counter < bytHash.Count(); counter++) {
                    long i = bytHash[counter] / 16;
                    if (i > 9) {
                        sTemp = ((char) (i - 10 + 0x41)).ToString();
                    }
                    else {
                        sTemp = ((char) (i + 0x30)).ToString();
                    }

                    i = bytHash[counter] % 16;
                    if (i > 9) {
                        sTemp += ((char) (i - 10 + 0x41)).ToString();
                    }
                    else {
                        sTemp += ((char) (i + 0x30)).ToString();
                    }

                    sHash += sTemp;
                }

                //根据大小写规则决定返回的字符串
                return toUpper ? sHash : sHash.ToLower();
            }
            catch (Exception ex) {
                throw new Exception(ex.Message);
            }
        }

        /// <summary>
        /// 计算16位MD5码
        /// </summary>
        /// <param name="word">字符串</param>
        /// <param name="toUpper">返回哈希值格式 true：英文大写，false：英文小写</param>
        /// <returns></returns>
        public static string Hash_MD5_16(string word, bool toUpper = true) {
            try {
                string sHash = Hash_MD5_32(word).Substring(8, 16);
                return toUpper ? sHash : sHash.ToLower();
            }
            catch (Exception ex) {
                throw new Exception(ex.Message);
            }
        }

        /// <summary>
        /// 计算32位2重MD5码
        /// </summary>
        /// <param name="word">字符串</param>
        /// <param name="toUpper">返回哈希值格式 true：英文大写，false：英文小写</param>
        /// <returns></returns>
        public static string Hash_2_MD5_32(string word, bool toUpper = true) {
            try {
                System.Security.Cryptography.MD5CryptoServiceProvider MD5CSP
                    = new System.Security.Cryptography.MD5CryptoServiceProvider();

                byte[] bytValue = System.Text.Encoding.UTF8.GetBytes(word);
                byte[] bytHash = MD5CSP.ComputeHash(bytValue);

                //根据计算得到的Hash码翻译为MD5码
                string sHash = "", sTemp = "";
                for (int counter = 0; counter < bytHash.Count(); counter++) {
                    long i = bytHash[counter] / 16;
                    if (i > 9) {
                        sTemp = ((char) (i - 10 + 0x41)).ToString();
                    }
                    else {
                        sTemp = ((char) (i + 0x30)).ToString();
                    }

                    i = bytHash[counter] % 16;
                    if (i > 9) {
                        sTemp += ((char) (i - 10 + 0x41)).ToString();
                    }
                    else {
                        sTemp += ((char) (i + 0x30)).ToString();
                    }

                    sHash += sTemp;
                }

                bytValue = System.Text.Encoding.UTF8.GetBytes(sHash);
                bytHash = MD5CSP.ComputeHash(bytValue);
                MD5CSP.Clear();
                sHash = "";

                //根据计算得到的Hash码翻译为MD5码
                for (int counter = 0; counter < bytHash.Count(); counter++) {
                    long i = bytHash[counter] / 16;
                    if (i > 9) {
                        sTemp = ((char) (i - 10 + 0x41)).ToString();
                    }
                    else {
                        sTemp = ((char) (i + 0x30)).ToString();
                    }

                    i = bytHash[counter] % 16;
                    if (i > 9) {
                        sTemp += ((char) (i - 10 + 0x41)).ToString();
                    }
                    else {
                        sTemp += ((char) (i + 0x30)).ToString();
                    }

                    sHash += sTemp;
                }

                //根据大小写规则决定返回的字符串
                return toUpper ? sHash : sHash.ToLower();
            }
            catch (Exception ex) {
                throw new Exception(ex.Message);
            }
        }

        /// <summary>
        /// 计算16位2重MD5码
        /// </summary>
        /// <param name="word">字符串</param>
        /// <param name="toUpper">返回哈希值格式 true：英文大写，false：英文小写</param>
        /// <returns></returns>
        public static string Hash_2_MD5_16(string word, bool toUpper = true) {
            try {
                System.Security.Cryptography.MD5CryptoServiceProvider MD5CSP
                    = new System.Security.Cryptography.MD5CryptoServiceProvider();

                byte[] bytValue = System.Text.Encoding.UTF8.GetBytes(word);
                byte[] bytHash = MD5CSP.ComputeHash(bytValue);

                //根据计算得到的Hash码翻译为MD5码
                string sHash = "", sTemp = "";
                for (int counter = 0; counter < bytHash.Count(); counter++) {
                    long i = bytHash[counter] / 16;
                    if (i > 9) {
                        sTemp = ((char) (i - 10 + 0x41)).ToString();
                    }
                    else {
                        sTemp = ((char) (i + 0x30)).ToString();
                    }

                    i = bytHash[counter] % 16;
                    if (i > 9) {
                        sTemp += ((char) (i - 10 + 0x41)).ToString();
                    }
                    else {
                        sTemp += ((char) (i + 0x30)).ToString();
                    }

                    sHash += sTemp;
                }

                sHash = sHash.Substring(8, 16);

                bytValue = System.Text.Encoding.UTF8.GetBytes(sHash);
                bytHash = MD5CSP.ComputeHash(bytValue);
                MD5CSP.Clear();
                sHash = "";

                //根据计算得到的Hash码翻译为MD5码
                for (int counter = 0; counter < bytHash.Count(); counter++) {
                    long i = bytHash[counter] / 16;
                    if (i > 9) {
                        sTemp = ((char) (i - 10 + 0x41)).ToString();
                    }
                    else {
                        sTemp = ((char) (i + 0x30)).ToString();
                    }

                    i = bytHash[counter] % 16;
                    if (i > 9) {
                        sTemp += ((char) (i - 10 + 0x41)).ToString();
                    }
                    else {
                        sTemp += ((char) (i + 0x30)).ToString();
                    }

                    sHash += sTemp;
                }

                sHash = sHash.Substring(8, 16);

                //根据大小写规则决定返回的字符串
                return toUpper ? sHash : sHash.ToLower();
            }
            catch (Exception ex) {
                throw new Exception(ex.Message);
            }
        }

        /// <summary>
        /// 计算SHA-1码
        /// </summary>
        /// <param name="word">字符串</param>
        /// <param name="toUpper">返回哈希值格式 true：英文大写，false：英文小写</param>
        /// <returns></returns>
        public static string Hash_SHA_1(string word, bool toUpper = true) {
            try {
                System.Security.Cryptography.SHA1CryptoServiceProvider SHA1CSP
                    = new System.Security.Cryptography.SHA1CryptoServiceProvider();

                byte[] bytValue = System.Text.Encoding.UTF8.GetBytes(word);
                byte[] bytHash = SHA1CSP.ComputeHash(bytValue);
                SHA1CSP.Clear();

                //根据计算得到的Hash码翻译为SHA-1码
                string sHash = "", sTemp = "";
                for (int counter = 0; counter < bytHash.Count(); counter++) {
                    long i = bytHash[counter] / 16;
                    if (i > 9) {
                        sTemp = ((char) (i - 10 + 0x41)).ToString();
                    }
                    else {
                        sTemp = ((char) (i + 0x30)).ToString();
                    }

                    i = bytHash[counter] % 16;
                    if (i > 9) {
                        sTemp += ((char) (i - 10 + 0x41)).ToString();
                    }
                    else {
                        sTemp += ((char) (i + 0x30)).ToString();
                    }

                    sHash += sTemp;
                }

                //根据大小写规则决定返回的字符串
                return toUpper ? sHash : sHash.ToLower();
            }
            catch (Exception ex) {
                throw new Exception(ex.Message);
            }
        }

        /// <summary>
        /// 计算SHA-256码
        /// </summary>
        /// <param name="word">字符串</param>
        /// <param name="toUpper">返回哈希值格式 true：英文大写，false：英文小写</param>
        /// <returns></returns>
        public static string Hash_SHA_256(string word, bool toUpper = true) {
            try {
                System.Security.Cryptography.SHA256CryptoServiceProvider SHA256CSP
                    = new System.Security.Cryptography.SHA256CryptoServiceProvider();

                byte[] bytValue = System.Text.Encoding.UTF8.GetBytes(word);
                byte[] bytHash = SHA256CSP.ComputeHash(bytValue);
                SHA256CSP.Clear();

                //根据计算得到的Hash码翻译为SHA-1码
                string sHash = "", sTemp = "";
                for (int counter = 0; counter < bytHash.Count(); counter++) {
                    long i = bytHash[counter] / 16;
                    if (i > 9) {
                        sTemp = ((char) (i - 10 + 0x41)).ToString();
                    }
                    else {
                        sTemp = ((char) (i + 0x30)).ToString();
                    }

                    i = bytHash[counter] % 16;
                    if (i > 9) {
                        sTemp += ((char) (i - 10 + 0x41)).ToString();
                    }
                    else {
                        sTemp += ((char) (i + 0x30)).ToString();
                    }

                    sHash += sTemp;
                }

                //根据大小写规则决定返回的字符串
                return toUpper ? sHash : sHash.ToLower();
            }
            catch (Exception ex) {
                throw new Exception(ex.Message);
            }
        }

        /// <summary>
        /// 计算SHA-384码
        /// </summary>
        /// <param name="word">字符串</param>
        /// <param name="toUpper">返回哈希值格式 true：英文大写，false：英文小写</param>
        /// <returns></returns>
        public static string Hash_SHA_384(string word, bool toUpper = true) {
            try {
                System.Security.Cryptography.SHA384CryptoServiceProvider SHA384CSP
                    = new System.Security.Cryptography.SHA384CryptoServiceProvider();

                byte[] bytValue = System.Text.Encoding.UTF8.GetBytes(word);
                byte[] bytHash = SHA384CSP.ComputeHash(bytValue);
                SHA384CSP.Clear();

                //根据计算得到的Hash码翻译为SHA-1码
                string sHash = "", sTemp = "";
                for (int counter = 0; counter < bytHash.Count(); counter++) {
                    long i = bytHash[counter] / 16;
                    if (i > 9) {
                        sTemp = ((char) (i - 10 + 0x41)).ToString();
                    }
                    else {
                        sTemp = ((char) (i + 0x30)).ToString();
                    }

                    i = bytHash[counter] % 16;
                    if (i > 9) {
                        sTemp += ((char) (i - 10 + 0x41)).ToString();
                    }
                    else {
                        sTemp += ((char) (i + 0x30)).ToString();
                    }

                    sHash += sTemp;
                }

                //根据大小写规则决定返回的字符串
                return toUpper ? sHash : sHash.ToLower();
            }
            catch (Exception ex) {
                throw new Exception(ex.Message);
            }
        }

        /// <summary>
        /// 计算SHA-512码
        /// </summary>
        /// <param name="word">字符串</param>
        /// <param name="toUpper">返回哈希值格式 true：英文大写，false：英文小写</param>
        /// <returns></returns>
        public static string Hash_SHA_512(string word, bool toUpper = true) {
            try {
                System.Security.Cryptography.SHA512CryptoServiceProvider SHA512CSP
                    = new System.Security.Cryptography.SHA512CryptoServiceProvider();

                byte[] bytValue = System.Text.Encoding.UTF8.GetBytes(word);
                byte[] bytHash = SHA512CSP.ComputeHash(bytValue);
                SHA512CSP.Clear();

                //根据计算得到的Hash码翻译为SHA-1码
                string sHash = "", sTemp = "";
                for (int counter = 0; counter < bytHash.Count(); counter++) {
                    long i = bytHash[counter] / 16;
                    if (i > 9) {
                        sTemp = ((char) (i - 10 + 0x41)).ToString();
                    }
                    else {
                        sTemp = ((char) (i + 0x30)).ToString();
                    }

                    i = bytHash[counter] % 16;
                    if (i > 9) {
                        sTemp += ((char) (i - 10 + 0x41)).ToString();
                    }
                    else {
                        sTemp += ((char) (i + 0x30)).ToString();
                    }

                    sHash += sTemp;
                }

                //根据大小写规则决定返回的字符串
                return toUpper ? sHash : sHash.ToLower();
            }
            catch (Exception ex) {
                throw new Exception(ex.Message);
            }
        }
    }
}